package org.jeecg.modules.rental.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.modules.rental.entity.WxArticle;
import org.jeecg.modules.rental.entity.WxArticleContent;
import org.jeecg.modules.rental.mapper.WxArticleContentMapper;
import org.jeecg.modules.rental.mapper.WxArticleMapper;
import org.jeecg.modules.rental.req.WxSDKConfigRequest;
import org.jeecg.modules.rental.resp.WxSDKConfigResponse;
import org.jeecg.modules.rental.util.WxAuthorizationUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.client.RestTemplate;
import org.springframework.stereotype.Controller;

import java.io.UnsupportedEncodingException;
import java.util.*;
@Api(tags = "租车支付账号")
@RestController
@Controller
@RequestMapping("/rental/wx")
@RequiredArgsConstructor
@Slf4j
public class WxConfigController {

    /*@Value("${wechat.appId:wxfb29804b6d5f621f}") // 如果 wechat.appId 未配置，默认为 defaultAppId
    private String appId;*/
    @Value("${wechat.appId:wx6b391fb9bad7d2f5}") // 如果 wechat.appId 未配置，默认为 defaultAppId
    private String appId;

    /*@Value("${wechat.appSecret:0886dc9ddbe6260add27a97fdb9a51b7}") // 如果 wechat.appSecret 未配置，默认为 defaultAppSecret
    private String appSecret;*/

    @Value("${wechat.appSecret:be415e0efc5eee4be6472f2e1ccfb104}") // 如果 wechat.appSecret 未配置，默认为 defaultAppSecret
    private String appSecret;
    private final WxAuthorizationUtil wxAuthorizationUtil;

    @Autowired
    private WxArticleMapper wxArticleMapper;

    @Autowired
    private WxArticleContentMapper wxArticleContentMapper;


    /*  private static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
    private static final String JSAPI_TICKET_URL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%s&type=jsapi";
*/
    @PostMapping("/getWxConfig")
    @ResponseBody
    public Result getWxConfig(@RequestBody WxSDKConfigRequest wxConfigRequest) {
        try {
            String url = wxConfigRequest.getUrl(); // 前端传递的当前网页 URL
            if (url == null || url.isEmpty()) {
                return Result.error("URL不能为空");
            }
            //  去掉 # 及其后面的部分
            url = url.split("#")[0];
            log.info("收到前端请求，URL: {}", url);
            // 1. 获取 access_token
            String accessToken = WxAuthorizationUtil.getAccessToken(appId,appSecret);
            if (accessToken == null) {
                log.error("获取 access_token 失败");
                return Result.error("获取 access_token 失败");
            }
            log.info("成功获取 access_token: {}", accessToken);

            // 2. 获取 jsapi_ticket
            String jsapiTicket = WxAuthorizationUtil.getJsapiTicket(accessToken);
            if (jsapiTicket == null) {
                log.error("获取 jsapi_ticket 失败");
                return Result.error("获取 jsapi_ticket 失败");
            }
            log.info("成功获取 jsapi_ticket: {}", jsapiTicket);

            // 3. 生成签名
            String timestamp = String.valueOf(System.currentTimeMillis() / 1000); // 时间戳
            String nonceStr = UUID.randomUUID().toString().replaceAll("-", "");  // 随机字符串
            String signature = WxAuthorizationUtil.generateSignature(jsapiTicket, nonceStr, timestamp, url);
            log.info("生成签名成功，signature: {}", signature);
            // 4. 返回配置信息
            WxSDKConfigResponse response = new WxSDKConfigResponse();
            response.setAppId(appId);
            response.setTimestamp(timestamp);
            response.setNonceStr(nonceStr);
            response.setSignature(signature);

            return Result.ok(response);

        } catch (Exception e) {
            e.printStackTrace();
            return Result.error("生成微信配置失败: " + e.getMessage());
        }
    }



    @PostMapping("/getPublishedList")
    @ResponseBody
    public Result<Map<String, Object>> getPublishedList(@RequestBody Map<String, Object> requestParams) {
        try {
            // 从请求参数中获取 offset, count, no_content，保证类型安全
            int offset = ((Number) requestParams.getOrDefault("offset", 0)).intValue();
            int count = ((Number) requestParams.getOrDefault("count", 10)).intValue();
            int noContent = ((Number) requestParams.getOrDefault("no_content", 0)).intValue();

            // 获取 access_token
            String accessToken = WxAuthorizationUtil.getAccessToken(appId, appSecret);
            if (accessToken == null || accessToken.isEmpty()) {
                log.error("获取 access_token 失败");
                return Result.error("获取 access_token 失败，请检查微信配置");
            }
            log.info("成功获取 access_token: {}", accessToken);

            // 调用微信接口获取成功发布的消息列表
            String url = "https://api.weixin.qq.com/cgi-bin/freepublish/batchget?access_token=" + accessToken;

            // 构建请求体
            Map<String, Object> requestBody = new HashMap<>();
            requestBody.put("offset", offset);
            requestBody.put("count", count);
            requestBody.put("no_content", noContent);

            // 使用 RestTemplate 发起 HTTP 请求
            RestTemplate restTemplate = new RestTemplate();
            HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(requestBody);

            // 接收响应为 String
            String response = restTemplate.postForObject(url, requestEntity, String.class);
            if (response == null || response.isEmpty()) {
                log.error("微信接口返回空响应");
                return Result.error("微信接口返回空响应");
            }

            // 使用 Jackson 将 JSON 字符串转换为 Map
            ObjectMapper objectMapper = new ObjectMapper();
            Map<String, Object> responseMap = objectMapper.readValue(response, Map.class);

            // 校验微信接口返回的结果
            if (responseMap.containsKey("errcode") && (Integer) responseMap.get("errcode") != 0) {
                log.error("微信接口返回错误: {}", responseMap);
                return Result.error("微信接口错误: " + responseMap.get("errmsg"));
            }

            // 成功返回结果
            log.info("成功获取发布列表: {}", responseMap);
            return Result.OK(responseMap );

        } catch (Exception e) {
            log.error("获取发布列表失败: {}", e.getMessage(), e);
            return Result.error("获取发布列表失败: " + e.getMessage());
        }
    }



    @PostMapping("/getPublishedArticle")
    @ResponseBody
    public Result<Object> getPublishedArticle(@RequestBody Map<String, Object> params) {
        try {
            // 获取 article_id
            String articleId = (String) params.get("id");
            if (articleId == null || articleId.trim().isEmpty()) {
                return Result.error("文章 ID 不能为空");
            }

            // 获取 access_token
            String accessToken = WxAuthorizationUtil.getAccessToken(appId, appSecret);
            if (accessToken == null || accessToken.isEmpty()) {
                log.error("获取 access_token 失败");
                return Result.error("获取 access_token 失败，请检查微信配置");
            }
            log.info("成功获取 access_token: {}", accessToken);

            // 调用微信接口获取文章信息
            String url = "https://api.weixin.qq.com/cgi-bin/freepublish/getarticle?access_token=" + accessToken;

            // 构建请求体
            Map<String, Object> requestBody = new HashMap<>();
            requestBody.put("article_id", articleId);

            // 发起 HTTP 请求
            RestTemplate restTemplate = new RestTemplate();
            HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(requestBody);
            String response = restTemplate.postForObject(url, requestEntity, String.class);

            // 解析响应
            ObjectMapper objectMapper = new ObjectMapper();
            Map<String, Object> responseMap = objectMapper.readValue(response, Map.class);

            // 校验响应是否包含错误
            if (responseMap.containsKey("errcode") && (Integer) responseMap.get("errcode") != 0) {
                log.error("微信接口返回错误: {}", responseMap);
                return Result.error("微信接口错误: " + responseMap.get("errmsg"));
            }

            // 返回文章详细信息
            log.info("成功获取文章内容: {}", responseMap);
            return Result.OK(responseMap );

        } catch (Exception e) {
            log.error("获取文章失败: {}", e.getMessage(), e);
            return Result.error("获取文章失败: " + e.getMessage());
        }
    }


    @PostMapping("/syncAllPublishedArticles")
    @ApiOperation(value = "同步微信所有已发布文章", notes = "从微信接口获取所有已发布文章并同步到数据库")
    public Result<String> syncAllPublishedArticles() {
        try {
            int offset = 0;
            int count = 20; // 每次获取的文章条数，微信接口默认最多支持 20 条
            int totalCount = 0;

            // 循环分页获取所有文章
            do {
                // 调用微信接口，获取文章列表
                Map<String, Object> response = getPublishedList(offset, count);
                if (response == null || response.isEmpty()) {
                    log.error("从微信接口获取文章失败");
                    return Result.error("从微信接口获取文章失败");
                }

                // 获取 total_count 和 item
                totalCount = (int) response.getOrDefault("total_count", 0);
                List<Map<String, Object>> items = (List<Map<String, Object>>) response.get("item");

                if (items != null && !items.isEmpty()) {
                    // 创建一个新的 HashMap 并同步当前页的文章数据
                    Map<String, Object> articleData = new HashMap<>();
                    articleData.put("item", items);
                    syncArticles(articleData);
                }

                // 更新偏移量，获取下一页
                offset += count;

            } while (offset < totalCount);

            return Result.OK("所有已发布文章同步完成！");
        } catch (Exception e) {
            log.error("同步微信已发布文章失败: {}", e.getMessage(), e);
            return Result.error("同步微信已发布文章失败: " + e.getMessage());
        }
    }

    /**
     * 调用微信接口获取已发布的文章列表
     *
     * @param offset 偏移量
     * @param count  每页条数
     * @return 返回微信接口的响应数据
     */
    private Map<String, Object> getPublishedList(int offset, int count) {
        try {
            // 获取 access_token
            String accessToken = WxAuthorizationUtil.getAccessToken(appId, appSecret);
            String url = "https://api.weixin.qq.com/cgi-bin/freepublish/batchget?access_token=" + accessToken;

            // 构建请求参数
            Map<String, Object> params = new HashMap<>();
            params.put("offset", offset);
            params.put("count", count);

            // 发起 HTTP 请求
            RestTemplate restTemplate = new RestTemplate();
            HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(params);
            String response = restTemplate.postForObject(url, requestEntity, String.class);

            // 使用 Jackson 解析 JSON 响应
            ObjectMapper objectMapper = new ObjectMapper();
            return objectMapper.readValue(response, Map.class);
        } catch (Exception e) {
            log.error("调用微信接口获取已发布文章列表失败: {}", e.getMessage(), e);
            return null;
        }
    }

    public void syncArticles(Map<String, Object> articleData) throws UnsupportedEncodingException {
        // 获取文章列表
        List<Map<String, Object>> items = (List<Map<String, Object>>) articleData.get("item");
        if (items == null || items.isEmpty()) {
            throw new RuntimeException("文章列表为空，无法同步");
        }

        for (Map<String, Object> item : items) {
            // 获取 article_id 和 update_time
            String articleId = (String) item.get("article_id");
            Long updateTimeTimestamp = ((Number) item.get("update_time")).longValue() * 1000;
            Date updateTime = new Date(updateTimeTimestamp);

            // 保存到 wx_article 表
            // 使用 LambdaQueryWrapper 查询 wx_article 表
            WxArticle article = wxArticleMapper.selectOne(
                    new LambdaQueryWrapper<WxArticle>()
                            .eq(WxArticle::getArticleId, articleId)
            );
            if (article == null) {
                // 如果文章不存在，新增记录
                article = new WxArticle();
                article.setArticleId(articleId);
                article.setCreateTime(new Date());
                article.setUpdateTime(updateTime);
                article.setArticleUpdateTime(updateTime);
                wxArticleMapper.insert(article);
            } else {
                // 如果文章已存在，仅更新更新时间
                article.setUpdateTime(updateTime);
                article.setArticleUpdateTime(updateTime);
                wxArticleMapper.updateById(article);
            }

            // 获取 content 并保存到 wx_article_content 表
            Map<String, Object> content = (Map<String, Object>) item.get("content");
            List<Map<String, Object>> newsItems = (List<Map<String, Object>>) content.get("news_item");

            if (newsItems != null) {
                for (Map<String, Object> newsItem : newsItems) {
                    String title = (String) newsItem.get("title");
                    byte[] bytes = title.getBytes("ISO-8859-1");
                    // 再将字节数组用 UTF-8 解码为正确的字符串
                    title = new String(bytes, "UTF-8");
                    String url = (String) newsItem.get("url");

                    // 检查文章内容是否已存在
                    WxArticleContent existingContent = wxArticleContentMapper.selectOne(
                            new LambdaQueryWrapper<WxArticleContent>()
                                    .eq(WxArticleContent::getArticleId, articleId)
                                    .eq(WxArticleContent::getTitle, title)
                                    .eq(WxArticleContent::getUrl, url)
                    );

                    if (existingContent == null) {
                        // 如果内容不存在，新增记录
                        WxArticleContent articleContent = new WxArticleContent();
                        articleContent.setArticleId(articleId);
                        articleContent.setTitle(title);
                        articleContent.setAuthor((String) newsItem.get("author"));
                        articleContent.setContentSourceUrl((String) newsItem.get("content_source_url"));
                        articleContent.setThumbMediaId((String) newsItem.get("thumb_media_id"));
                        articleContent.setUrl(url);
                        articleContent.setThumbUrl((String) newsItem.get("thumb_url"));
                        articleContent.setIsDeleted(Boolean.TRUE.equals(newsItem.get("is_deleted")) ? "1" : "0");
                        articleContent.setCreateTime(new Date());

                        // 保存到数据库
                        wxArticleContentMapper.insert(articleContent);
                    } else {
                        // 如果内容已存在，则更新相关字段（如需要）
                        existingContent.setAuthor((String) newsItem.get("author"));
                        existingContent.setContentSourceUrl((String) newsItem.get("content_source_url"));
                        existingContent.setThumbMediaId((String) newsItem.get("thumb_media_id"));
                        existingContent.setThumbUrl((String) newsItem.get("thumb_url"));
                        existingContent.setIsDeleted(Boolean.TRUE.equals(newsItem.get("is_deleted")) ? "1" : "0");
                        wxArticleContentMapper.updateById(existingContent);
                    }
                }
            }
        }
    }

    @ApiOperation(value = "获取前五条轮播内容列表", notes = "查询前五条轮播内容，支持按标题模糊查询")
    @GetMapping("/carousel/list")
    public Result<List<WxArticleContent>> getCarouselList(
            @RequestParam(name = "title", required = false) String title) {

        try {


            // 执行查询
            List<WxArticleContent> records = wxArticleContentMapper.getCarouselList(title);

            return Result.OK(records);
        } catch (Exception e) {
            log.error("获取轮播内容列表失败: {}", e.getMessage(), e);
            return Result.error("获取轮播内容列表失败");
        }
    }


 }